package org.kernely.ui.login;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.kernely.core.service.KernelyBundleService;
import org.kernely.security.dao.UserDAO;
import org.kernely.security.persistence.User;
import org.kernely.security.service.KernelySecurityService;
import org.kernely.ui.MainApplication;
import org.kernely.ui.mvp.KernelyEventBus;
import org.kernely.ui.mvp.KernelyPresenter;

import com.vaadin.terminal.UserError;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickListener;

/**
 *	Presenter of the login page.
 */
public class KernelyLoginPresenter extends KernelyPresenter<KernelyLoginView> {

	@Override
	/**
	 * @see org.kernely.core.service.IKernelyPresenter#bind()
	 */
	public void bind() {
		// Associate a listener to this button
		this.view.getClearButton().addListener(new ClickListener(){
			private static final long serialVersionUID = -3981156745770104227L;
			// Action called when the button is clicked
			public void buttonClick (Button.ClickEvent event) {
				view.getPassword().setValue("");
				view.getLogin().setValue("");
				view.getLogin().focus();
			}
		});
		// Associate a listener to this button
		this.view.getLoginButton().addListener(new ClickListener(){

			private static final long serialVersionUID = -6987749178873430449L;
			// Action called when the button is clicked
			public void buttonClick (Button.ClickEvent event) {
				loginProcess();
			}
		});
	}


	private void loginProcess() {
		UserDAO userdao = new UserDAO();
		Subject user = SecurityUtils.getSubject();
		// Create a token with the username and the password
		UsernamePasswordToken token = new UsernamePasswordToken((String)this.view.getLogin().getValue(), (String)this.view.getPassword().getValue());

		try {
			// try to connect : ask the KernelyRealm
			user.login(token);

			// Store the user into the Kernely security service
			User current = userdao.findUser((String)this.view.getLogin().getValue());
			MainApplication.getSecurityService().setCurrentUser(current);
		} catch ( UnknownAccountException uae ) {
			
//			MainApplication.getLogger().log(LogService.LOG_DEBUG, uae.getMessage());
			uae.printStackTrace();
			this.view.getForm().setComponentError(new UserError("No user found for this username and password."));
		} catch ( IncorrectCredentialsException ice ) {
//			MainApplication.getLogger().log(LogService.LOG_DEBUG, ice.getMessage());
			ice.printStackTrace();
			this.view.getForm().setComponentError(new UserError("No user found for this username and password."));
		} catch ( LockedAccountException lae ) {
//			MainApplication.getLogger().log(LogService.LOG_DEBUG, lae.getMessage());
			lae.printStackTrace();
			this.view.getForm().setComponentError(new UserError("Access not granted"));
		} catch ( AuthenticationException ae ) {
//			MainApplication.getLogger().log(LogService.LOG_DEBUG, ae.getMessage());
			ae.printStackTrace();
			this.view.getForm().setComponentError(new UserError("No user found for this username and password."));
		} catch (Exception e){
//			MainApplication.getLogger().log(LogService.LOG_DEBUG, e.getMessage());
			e.printStackTrace();
			this.view.getForm().setComponentError(new UserError("Exception in the authentication process."));
		}
		if(user.isAuthenticated()){
			Session session = SecurityUtils.getSubject().getSession();

			KernelyEventBus eventBus = (KernelyEventBus) session.getAttribute("eventBus");
			eventBus.broadcastEvent(new KernelyLoginEvent(this));
		}

	}

}
